TARGET    := led-blink

# 存放所有生成文件的目录
BUILD_DIR := ./Build

# ARM GCC 工具链
TOOLCHAIN := arm-none-eabi-
CC  := $(TOOLCHAIN)gcc
CP  := $(TOOLCHAIN)objcopy
AS  := $(TOOLCHAIN)gcc -x assembler-with-cpp
SZ  := $(TOOLCHAIN)size
HEX := $(CP) -O ihex
BIN := $(CP) -O binary -S




############################################# 标准库源码 ###################################################
SRC_FILES := ./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7/startup_stm32f10x_hd.s
SRC_FILES += ./Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
SRC_FILES += ./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c
SRC_FILES += $(wildcard ./Libraries/STM32F10x_StdPeriph_Driver/src/*.c)

############################################# 头文件路径 ###################################################
INC_DIRS  := ./Libraries/CMSIS/CM3/CoreSupport/
INC_DIRS  += ./Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/
INC_DIRS  += ./Libraries/STM32F10x_StdPeriph_Driver/inc/
INC_DIRS  += $(shell find ./User -type d)

############################################## 用户源码 ####################################################
SRC_FILES += $(shell find ./User -name "*.c" -type f)




# 内核架构
CPU := cortex-m3
# 预定义宏
DEFS := -D STM32F10X_HD  -D USE_STDPERIPH_DRIVER
# 链接脚本
LINK_SCRIPT := ./STM32F103ZETx_FLASH.ld
# 编译参数
CP_FLAGS := $(DEFS) $(addprefix -I,$(INC_DIRS)) -mcpu=$(CPU) -g -gdwarf-2 -mthumb -Os -Wall -Wextra -fdata-sections -ffunction-sections -fmessage-length=0 -MMD -MP 
# 汇编参数
AS_FLAGS := $(CP_FLAGS)
# 链接参数
LD_FLAGS := -mcpu=$(CPU) -T $(LINK_SCRIPT) -specs=nano.specs -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref,--gc-sections,--print-memory-usage,--no-warn-rwx-segments




# 设置文件搜索路径，.h 文件路径由 gcc -I 参数指定
VPATH := $(sort $(dir $(SRC_FILES)))
# 保留 .o 文件，make 可能会删除生成的 .o 文件
.PRECIOUS: $(BUILD_DIR)/%.o




.PHONY: all
all: $(BUILD_DIR) $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).bin $(BUILD_DIR)/$(TARGET).hex


%.elf: $(addprefix $(BUILD_DIR)/,$(notdir $(addsuffix .o,$(SRC_FILES))))
	@echo "[ Linking   ] $@"
	@$(CC) $(LD_FLAGS) $^ -o $@

$(BUILD_DIR)/%.c.o: %.c
	@echo "[ Compiling ] $<"
	@$(CC) -c $(CP_FLAGS) $< -o $@

$(BUILD_DIR)/%.s.o: %.s
	@echo "[ Compiling ] $<"
	@$(AS) -c $(AS_FLAGS) $< -o $@

%.hex: %.elf
	@$(HEX) $< $@

%.bin: %.elf
	@$(BIN) $< $@

$(BUILD_DIR):
	@mkdir -p $@




clean:
	@rm $(BUILD_DIR)/ -rf

st-flash: all
	@st-flash --format ihex write $(BUILD_DIR)/$(TARGET).hex

st-erase:
	@st-flash erase

isp-flash: all
	@stm32flash -b 115200 -i '-dtr&rts,dtr:-dtr&-rts,dtr' -v -w $(BUILD_DIR)/$(TARGET).bin /dev/ttyUSB0

isp-erase:
	@stm32flash -b 115200 -i '-dtr&rts,dtr:-dtr&-rts,dtr' -o /dev/ttyUSB0

isp-info:
	@stm32flash -b 115200 -i '-dtr&rts,dtr:-dtr&-rts,dtr' /dev/ttyUSB0

debug: all
	-@pgrep openocd || openocd -f /usr/share/openocd/scripts/interface/stlink.cfg -f /usr/share/openocd/scripts/target/stm32f1x.cfg &> /dev/null &
	-@sleep 2 && gdb $(BUILD_DIR)/$(TARGET).elf
	-@sleep 1 && killall openocd

rebuild: clean all

install: st-flash




# 头文件相关的规则并不在上面的规则中，这会导致头文件修改后不会重新编译（除非 make clean）
# 所以需由 gcc -MMD 参数生成 .d 文件（包含了头文件的依赖规则）
-include $(BUILD_DIR)/*.d
